﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Globalization;

namespace Elentok.Common.Helpers
{
  /// <summary>
  /// Contains various registry methods
  /// </summary>
  public static class RegistryHelper
  {
    /// <summary>
    /// Returns the registry value kind from the given string
    /// ("REG_SZ" will return RegistryValueKind.String, etc..)
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static RegistryValueKind ValueKindFromString(string type)
    {
      switch (type)
      {
        case "REG_SZ":
          return RegistryValueKind.String;
        case "REG_EXPAND_SZ":
          return RegistryValueKind.ExpandString;
        case "REG_BINARY":
          return RegistryValueKind.Binary;
        case "REG_DWORD":
          return RegistryValueKind.DWord;
        case "REG_MULTI_SZ":
          return RegistryValueKind.MultiString;
        case "REG_QWORD":
          return RegistryValueKind.QWord;
        default:
          return RegistryValueKind.Unknown;
      }
    }

    /// <summary>
    /// Gets one of "HKEY_LOCAL_MACHINE", "KEY_CURRENT_USER", etc... and returns 
    /// the appropriate RegistryKey object.
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public static RegistryKey BaseKeyFromString(string key)
    {
      switch (key)
      {
        case "HKEY_CURRENT_USER":
          return Registry.CurrentUser;
        case "HKEY_CLASSES_ROOT":
          return Registry.ClassesRoot;
        case "HKEY_LOCAL_MACHINE":
          return Registry.LocalMachine;
        case "HKEY_USERS":
          return Registry.Users;
        case "HKEY_CURRENT_CONFIG":
          return Registry.CurrentConfig;
        default:
          throw new ArgumentOutOfRangeException(
            "key",
            string.Format(CultureInfo.CurrentCulture, "Invalid registry key '{0}'", key));
      }
    }

    /// <summary>
    /// Gets a full registry key path (e.g. "HKEY_CURRENT_USER\Environment\...")
    /// and returns the appropriate RegistryKey object
    /// </summary>
    /// <param name="key"></param>
    /// <param name="writable">Set to true if you need write access to the key</param>
    /// <returns></returns>
    public static RegistryKey KeyFromString(string key, bool writable)
    {
      string[] keyParts = key.Split(new char[] { '\\' }, 2);

      RegistryKey baseKey = BaseKeyFromString(keyParts[0]);

      string subKeyPath = keyParts[1];

      RegistryKey subKey = baseKey.OpenSubKey(subKeyPath, writable);

      if (subKey == null)
        subKey = baseKey.CreateSubKey(subKeyPath);

      return subKey;
    }
  }
}
